/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package GameFrameworkJavaFX;
 
import Actors.Ball;
import Actors.Actor;
import Actors.Bricks;
import Actors.walls;
import Actors.Enemy;
import static GameFrameworkJavaFX.GameState.TitleScreen;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
 
/**
 *
 * @author anc
 */
public class Game {
 
   
    private GameState gameState = GameState.TitleScreen;
    private static Game game;
    private final Gui gui;
 
    Bricks bricks;
    Actor bat;
    Ball multiball;
    Ball multiball2;
    Ball ball;
    Actor bricks1p;
    Actor bricks2p;
    Actor bricks0p;
    walls wallsTop;
    walls wallsMid;
    walls wallsBot;
 
    Actor enemy;
    public int enemycount = 0;
    public int enemyhitpoint = 2;
    public int levelcounter = 0;
    public int brickCounter = 0;
    private int life = 3;
    public int enemyAge = 0;
    public boolean level1 = false;
    public boolean level2 = false;
    public boolean level3 = false;
    public boolean ballAlive = false;
    public boolean batEdge = false;
    public boolean batLong = false;
    public boolean batShort = false;
    public boolean fireBall = false;
    public boolean speedDown = false;
    public boolean spDownUp = false;
    public boolean multiBall = true;
   
   
    public boolean enemySpawn = false;
 
    public boolean gravity = false;
   
    public boolean gravityOnBat = false;
   
    public int fireAge = 0;
    public int distBall = 0;
    public int speedAge = 0;
    public int multiAge = 0;
    public int gravityAge = 0;
   
   
    int batMid;
    int batTop;
    int batBot;
    int test;
    int test2;
    int test3;
   
    private int BRICKS1p_COLUMNS ;
    private int BRICKS1p_ROWS ;
   
    private int BRICKS0p_COLUMNS ;
    private int BRICKS0p_ROWS ;
   
    private int BRICKS2p_COLUMNS ;
    private int BRICKS2p_ROWS ;
   
    public int consumedBricks = 0;
    private final ArrayList<Actor> actors;
 
    public int ballCount = 1;
 
    private Game(Gui gui) {
        this.gui = gui;
        actors = new ArrayList();
 
    }
 
    public static Game getInstance() {
        return game;
    }
 
    public static void createGameAndSetGui(Gui gui) {
        game = new Game(gui);
    }
 
    public ArrayList<Actor> getActors() {
        return actors;
    }
 
    public void removeActorFromWorld(Actor actor) {
        actors.remove(actor);
        gui.removeImageView(actor.getImageView());
    }
    //Method for creating actors
    public final void createActors() {
        System.out.println("Creating actors...");
 
        ball = new Ball("Ball", "ball.png", 30);
        this.ball.setBallHeight(50);
        this.ball.setBallWidth(50);
        addToWorld(ball, 1270, 390, 0, 0, 1);
 
        bat = new Actor("Bat", "bat_yeah.png", 0);
        this.bat.setHeight(215);
        this.bat.setWidth(50);
        addToWorld(bat, 1300, 300, 0, 0, 1);
 
        wallsTop = new walls("wall", "wall.png", 0);
 
        this.wallsTop.setHeight(20);
        this.wallsTop.setWidth(1800);
        addToWorld(wallsTop, 21, 50, 0, 0, 1);
 
        wallsBot = new walls("wall", "wall.png", 0);
 
        wallsBot.setLocation(21, 652);
        this.wallsBot.setHeight(20);
        this.wallsBot.setWidth(1800);
        addToWorld(wallsBot, 21, 652, 0, 0, 1);
 
        wallsMid = new walls("wall", "wallmid2.png", 0);
 
        wallsMid.setLocation(1, 50);
        this.wallsMid.setHeight(1000);
        this.wallsMid.setWidth(20);
        addToWorld(wallsMid, 1, 50, 0, 0, 1);
 
        addBricks();
    }
   
    //Method for creating all the bricks
    public void addBricks() {
       if(level1 == true){
       BRICKS1p_COLUMNS = 2;
       BRICKS1p_ROWS = 5;
   
       BRICKS0p_COLUMNS = 1;
       BRICKS0p_ROWS = 5;
   
       BRICKS2p_COLUMNS = 1;
       BRICKS2p_ROWS = 5;    
       }
       else if(level2 == true){
       BRICKS1p_COLUMNS = 2;
       BRICKS1p_ROWS = 5;
   
       BRICKS0p_COLUMNS = 1;
       BRICKS0p_ROWS = 5;
   
       BRICKS2p_COLUMNS = 2;
       BRICKS2p_ROWS = 5;
       }
       else if (level3 == true){
        BRICKS1p_COLUMNS = 2;
        BRICKS1p_ROWS = 5;
   
        BRICKS0p_COLUMNS = 1;
       BRICKS0p_ROWS = 5;
   
       BRICKS2p_COLUMNS = 3;
        BRICKS2p_ROWS = 5;
       }
        for (int x = 0; x < BRICKS1p_COLUMNS; x++) {
            for (int y = 0; y < BRICKS1p_ROWS; y++) {
 
                bricks1p = (new Bricks("bricks1p", "brick1p.png", 30, 30, 60));
                addToWorld(bricks1p, 200 + x * 100, 120 + y * 100, 0, 0, 1);
               
                   
               
            }
        }
       
        for (int x = 0; x < BRICKS0p_COLUMNS; x++) {
            for (int y = 0; y < BRICKS0p_ROWS; y++) {
 
                bricks0p = (new Bricks("bricks0p", "brick0p.png", 30, 30, 60));
                addToWorld(bricks0p, 400 + x * 100, 120 + y * 100, 0, 0, 1);
               
            }
        }
       
        for (int x = 0; x < BRICKS2p_COLUMNS; x++) {
            for (int y = 0; y < BRICKS2p_ROWS; y++) {
 
                bricks2p = (new Bricks("bricks2p", "brick2p.png", 30, 30, 60));
                addToWorld(bricks2p, 500 + x * 100, 120 + y * 100, 0, 0, 1);
               
            }
        }
    }
   
 
    public void addToWorld(Actor actor, int x, int y, int xSpeed, int ySpeed, double collisionRadius) {
        actor.setLocation(x, y);
        actor.setSpeedX(xSpeed);
        actor.setSpeedY(ySpeed);
        actor.setCollisionRadius(collisionRadius);
        actors.add(actor);
        gui.addImageView(actor.getImageView());
    }
 
    // Method for creating ball and bat from start while loosing a life
    public void createBatBall(){
        ball = new Ball("Ball", "ball.png", 30);
        this.ball.setBallHeight(50);
        this.ball.setBallWidth(50);
        addToWorld(ball, 1270, 390, 0, 0, 1);
 
       
        bat = new Actor("Bat", "bat_yeah.png", 0);
        this.bat.setHeight(215);
        this.bat.setWidth(50);
        addToWorld(bat, 1300, 300, 0, 0, 1);
   
    }
   
    //Method for enemyspawning
    public void spawn() {
        Random random = new Random();
        boolean check = false;
        boolean enemyPos = false;
   
        int min = 100;
        int max = 700;
   
   
        int rx = random.nextInt((min) + max -400) +750;
        int ry = random.nextInt((min + 450) -100) +80;
   
    if (enemySpawn == true ){
 
        enemy = (new Enemy("Enemy", "enemy.png",80,30,60));
        addToWorld(enemy,rx, ry, 0, 0, 1);
        enemySpawn = false;
        enemy.setSpeedY(-3);
 
        enemy.setSpeedX(-2);
     }
    }
     
    //Method for changing direction of ball if colliding with bat
    public void collissionBall() {
 
        batMid = bat.getHeight() / 2;
        batTop = bat.getHeight() % 10;
        batBot = bat.getHeight() % 90;
        test = ball.getY() - bat.getY() + (ball.getBallHeight() / 2);
 
        if (gravity == false) {
            if (speedDown == false) {
               
                if (ball.collidesWith(bat)) {
                ball.setSpeedY((test - batMid) / 10);
                ball.setSpeedX(ball.getSpeedX() * -1);
                }
            }
           
            if (speedDown == true) {
               
                if (ball.collidesWith(bat)) {
                    ball.setSpeedY((test - batMid) / 10);
                    ball.setSpeedX(-8);
                }
            }
 
        }
       
        if (gravity == true) {
            if(ball.collidesWith(bat)) {
                ball.setSpeedY(0);
                ball.setSpeedX(0);
                ballAlive = false;
                ball.setX(ball.getX() -10);
                gravityOnBat = true;
                distBall = ball.getY() - bat.getY();
            }
           
            if(gravityOnBat == true) {
               
                ball.setY(bat.getY() + distBall);
            }
        }
        if (multiBall == false){
            if (multiball != null && multiball.collidesWith(bat)){
                multiball.setSpeedY((test - batMid) / 10);
                multiball.setSpeedX(multiball.getSpeedX() * -1);
            }
            else if (multiball2 != null && multiball2.collidesWith(bat)){
                multiball2.setSpeedY((test - batMid) / 10);
                multiball2.setSpeedX(multiball2.getSpeedX() * -1);
            }
        }
 
    }
   
    //Method for checking ball collission with walls
    public void collissionWall() {
 
        if (ball.collidesWith(wallsMid)) {
            ball.setSpeedX(-ball.getSpeedX());
        }
 
        if (ball.collidesWith(wallsTop)) {
            ball.setSpeedY(-ball.getSpeedY());
        }
 
        if (ball.collidesWith(wallsBot)) {
            ball.setSpeedY(-ball.getSpeedY());
        }
 
        if (bat.collidesWith(wallsTop)) {
           
            bat.setLocation(1300, 71);
        }
       
        if(batLong == false) {
           
            if(batShort == true) {
                if (bat.collidesWith(wallsBot)) {
                  bat.setLocation(1300, 479);
                }
            }
           
            else if (bat.collidesWith(wallsBot)) {
           
            bat.setLocation(1300, 439);
            }
           
        }
       
        else if(batLong == true) {
 
            if (bat.collidesWith(wallsBot)) {
           
            bat.setLocation(1300, 405);
            }
        }
    }
    //Method for changing level
    public void ChangeLevel(){
       
         if( level1 == true && brickCounter == 20){
           
            level1 = false;
            removeAllActors();
            level2 = true;
            brickCounter = 0;
            ballAlive = false;
            life = 3;
            consumedBricks = 0;
            gui.updateLife(life);
            gui.updateScore(consumedBricks);
            fireBall = false;
            batLong = false;
            batShort = false;
            gravity = false;
            levelcounter++;
        }
        if (level2 == true && levelcounter == 1){
           
            createActors();
            levelcounter++;
        }
        if (level2 == true && brickCounter ==25){
           
            level2 = false;
            removeAllActors();
            level3 = true;
            brickCounter = 0;
            ballAlive = false;
            life = 3;
            consumedBricks = 0;
            gui.updateLife(life);
            gui.updateScore(consumedBricks);
            fireBall = false;
            batLong = false;
            batShort = false;
            gravity = false;
           
        }
       
        if (level3 == true && levelcounter == 2){
           
            createActors();
            levelcounter++;
           
        }
        if (level3 == true && brickCounter == 30){
           
            removeAllActors();
            level3 = false;
            brickCounter = 0;
            ballAlive = false;
            life = 3;
            consumedBricks = 0;
            gui.updateLife(life);
            gui.updateScore(consumedBricks);
            fireBall = false;
            batLong = false;
            batShort = false;
            gravity = false;
            setGameState(gameState.GameComplete);
        }
    }
   
   
    public void timeTick() {
 
        //First all actors do their default actions.
 
        for (Actor actor: actors){
            actor.timeTick();
        }
           
 
       
        ChangeLevel();
        collissionWall();
        collissionBall();
        ballPaddle();
        spawn();
 
 
        //Checks all collissions  
        for (Actor actor: actors){
           
            if(enemy != null && actor.getName().equals("bricks2p") && actor.collidesWith(enemy) ){
                enemy.setSpeedY(-enemy.getSpeedY());
                enemy.setSpeedX(-enemy.getSpeedX());
               
            }
            else if(enemy != null&&actor.getName().equals("bricks0p") && actor.collidesWith(enemy) ){
                enemy.setSpeedY(-enemy.getSpeedY());
                enemy.setSpeedX(-enemy.getSpeedX());
               
            }
            else if(enemy != null && actor.getName().equals("bricks1p") && actor.collidesWith(enemy) ){
                enemy.setSpeedY(-enemy.getSpeedY());
                enemy.setSpeedX(-enemy.getSpeedX());
               
            }
           
            else if(enemy != null && multiball != null && multiball2 != null && actor.getName().equals("MultiBall") && actor.collidesWith(enemy) ){
                removeActorFromWorld(enemy);
            }
           
            else if (enemy != null && enemy.atHorizontalEdge()){
                enemyhitpoint = 2;
                removeActorFromWorld(enemy);
            }
           
        }
       //This loop checks for object collissions
       for (Actor actor : actors) {
            if(enemySpawn == false){
                enemyAge++;
            }
           
            if (enemyAge >= 15000) {
                enemySpawn = true;
                enemyAge = 0;
            }
           
            if (actor.getName().equals("Ball") && actor.atHorizontalEdge() && life >0 ){
               
                fireBall = false;
                batLong = false;
                batShort = false;
                gravity = false;
                speedDown = false;
               
                removeActorFromWorld(multiball);
                removeActorFromWorld(multiball2);
                life--;
                gui.updateLife(life);
                removeActorFromWorld(actor);
                removeActorFromWorld(bat);
                ballAlive = false;
                createBatBall();
                break;
            }
           else if (actor.getName().equals("Ball") && actor.atHorizontalEdge() && life == 0) {
           
            fireBall = false;
            batLong = false;
            batShort = false;
            gravity = false;
            speedDown = false;
            removeActorFromWorld(multiball);
            removeActorFromWorld(multiball2);
           
            removeAllActors();
            setGameState(GameState.GameOver);
            ballAlive = false;
            life = 3;
            consumedBricks = 0;
            gui.updateLife(life);
            gui.updateScore(consumedBricks);
            break;
            }
           
            //MultiBall PowerUP Wall Collision
            else if(actor.getName().equals("MultiBall") && actor.collidesWith(wallsTop)){
              actor.setSpeedY(-actor.getSpeedY());
       
       
            }
       
            else if (actor.getName().equals("MultiBall") && actor.collidesWith(wallsBot)){
               
                actor.setSpeedY(-actor.getSpeedY());
               
            }
           
            else if (actor.getName().equals("MultiBall") && actor.collidesWith(wallsMid)){
               
                actor.setSpeedX(-actor.getSpeedX());
               
            }
           
            //MultiBall PowerUP Bricks Collision
            //MultiBall 1
            else if (actor.getName().equals("bricks2p") && multiball != null && actor.collidesWith(multiball)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball) || brick.bottomEdge.collidesWith(multiball)){
                        multiball.setSpeedY(-multiball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball) || brick.rightEdge.collidesWith(multiball)) {
                        multiball.setSpeedX(-multiball.getSpeedX());
                   
                    }
                   
                    if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    consumedBricks+=2;
                    brickCounter++;
                    gui.updateScore(consumedBricks);
                    }
            }
           
            else if (actor.getName().equals("bricks1p") && multiball != null && actor.collidesWith(multiball)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball) || brick.bottomEdge.collidesWith(multiball)){
                        multiball.setSpeedY(-multiball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball) || brick.rightEdge.collidesWith(multiball)) {
                        multiball.setSpeedX(-multiball.getSpeedX());
                   
                    }
                   
                    removeActorFromWorld(actor);
                    consumedBricks++;
                    brickCounter ++;
                    gui.updateScore(consumedBricks);
            }
           
            else if (actor.getName().equals("bricks0p") && multiball != null && actor.collidesWith(multiball)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball) || brick.bottomEdge.collidesWith(multiball)){
                        multiball.setSpeedY(-multiball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball) || brick.rightEdge.collidesWith(multiball)) {
                        multiball.setSpeedX(-multiball.getSpeedX());
                   
                    }
                   
                    if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    brickCounter++;
                }
            }
           
            //MultiBall 2
            else if (actor.getName().equals("bricks2p") && multiball2 != null && actor.collidesWith(multiball2)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball2) || brick.bottomEdge.collidesWith(multiball2)){
                        multiball2.setSpeedY(-multiball2.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball2) || brick.rightEdge.collidesWith(multiball2)) {
                        multiball2.setSpeedX(-multiball2.getSpeedX());
                   
                    }
                   
                    if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    consumedBricks+=2;
                    brickCounter++;
                    gui.updateScore(consumedBricks);
                    }
            }
           
            else if (actor.getName().equals("bricks1p") && multiball2 != null && actor.collidesWith(multiball2)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball2) || brick.bottomEdge.collidesWith(multiball2)){
                        multiball2.setSpeedY(-multiball2.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball2) || brick.rightEdge.collidesWith(multiball2)) {
                        multiball2.setSpeedX(-multiball2.getSpeedX());
                   
                    }
                   
                    removeActorFromWorld(actor);
                    consumedBricks++;
                    brickCounter ++;
                    gui.updateScore(consumedBricks);
            }
           
            else if (actor.getName().equals("bricks0p") && multiball2 != null && actor.collidesWith(multiball2)){
                Bricks brick = (Bricks)actor;
                brick.counter--;
 
                    if (brick.topEdge.collidesWith(multiball2) || brick.bottomEdge.collidesWith(multiball2)){
                        multiball2.setSpeedY(-multiball2.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(multiball2) || brick.rightEdge.collidesWith(multiball2)) {
                        multiball2.setSpeedX(-multiball2.getSpeedX());
                   
                    }
                   
                    if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    brickCounter++;
                }
            }
 
            //MultiBall At Horizontal Edge
            if (actor.getName().equals("MultiBall") && actor.atHorizontalEdge() && life >=0 ){
                removeActorFromWorld(actor);
            }
           
            //Checks ball collission with bricks
            else if (actor.getName().equals("bricks1p") && actor.collidesWith(ball)) {
                Bricks brick = (Bricks)actor;
                   
                powerUps();
                if (fireBall == false) {
                   
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        ball.setSpeedY(-ball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        ball.setSpeedX(-ball.getSpeedX());
                    }
                }
               
                else if (fireBall == true) {
                   
                    brick.counter = 0;
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        removeActorFromWorld(actor);
                       
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        removeActorFromWorld(actor);
                    }
                }
 
                removeActorFromWorld(actor);
                consumedBricks++;
                brickCounter ++;
                gui.updateScore(consumedBricks);
            }
            //Checks ball collission with bricks
            else if (actor.getName().equals("bricks0p") && actor.collidesWith(ball)) {
                Bricks brick = (Bricks)actor;
               
                powerUps();
                brick.counter--;
                if (fireBall == false) {
                   
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        ball.setSpeedY(-ball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        ball.setSpeedX(-ball.getSpeedX());
                    }
                }
               
                else if (fireBall == true) {
                   
                    brick.counter = 0;
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        removeActorFromWorld(actor);
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        removeActorFromWorld(actor);
                    }
                }
               
                if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    brickCounter++;
                }
            }
           
           
            //Checks ball collission with bricks
            else if (actor.getName().equals("bricks2p") && actor.collidesWith(ball)) {
                Bricks brick = (Bricks)actor;
               
                powerUps();
               
                brick.counter--;
 
                if (fireBall == false) {
                   
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        ball.setSpeedY(-ball.getSpeedY());
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        ball.setSpeedX(-ball.getSpeedX());
                    }
                }
               
                else if (fireBall == true) {
 
                    brick.counter = 0;
 
                    if (brick.topEdge.collidesWith(ball) || brick.bottomEdge.collidesWith(ball)){
                        removeActorFromWorld(actor);
                    }
               
                    if (brick.leftEdge.collidesWith(ball) || brick.rightEdge.collidesWith(ball)) {
                        removeActorFromWorld(actor);
                    }
                }
               
                if (brick.counter == 0) {
                    removeActorFromWorld(actor);
                    consumedBricks+=2;
                    brickCounter++;
                    gui.updateScore(consumedBricks);
                }
 
            }
           
           if (gravity == true) {
               gravityAge++;
           }
           
           if (gravityAge >= 10000) {
               gravity = false;
           }
            
            if (multiBall == false) {
                multiAge++;
               
               
            }
           
            if (multiAge >= 15000) {
                if (actor.getName().equals("MultiBall") && multiBall == false) {
                  removeActorFromWorld(actor);
                }
                if (actor.getName().equals("MultiBall") && multiBall == false) {
                  removeActorFromWorld(actor);
                }
            }
           
            if (multiAge >= 20000) {
                multiAge = 0;
                multiBall = true;
            }
           
            if (speedDown == true) {
                    speedAge++;
                   
                    if (speedAge > 4000) {
                        speedAge = 0;
                       
                        spDownUp = true;
                        speedDown = false;
               
                        System.out.println("Power UP: SP DOWN END");
                    }
            }
           
           
           
            if (spDownUp == true) {
                if (ball.collidesWith(bat)) {
                    ball.setSpeedX(-15);
                    spDownUp = false;
                }
            }
           
            if (fireBall == true) {
                    fireAge++;
            }
               
            if (fireAge >= 300) {
                ball.updateImage(new Image(getClass().getResourceAsStream("/resources/" + "ball.png")));
                fireBall = false;
                fireAge = 0;
                   
            }
       
            //checks enemy collision with ball depending on level
            if (level1 == true && actor.getName().equals("Enemy") && actor.collidesWith(ball)){
                ball.setSpeedX(-ball.getSpeedX());
                ball.setSpeedY(-ball.getSpeedY());
                removeActorFromWorld(actor);
            }
           
            else if (level2 == true && actor.getName().equals("Enemy") && actor.collidesWith(ball)){
                ball.setSpeedX(-ball.getSpeedX());
                ball.setSpeedY(-ball.getSpeedY());
                removeActorFromWorld(actor);
            }
           
            else if (level3 == true && actor.getName().equals("Enemy") && actor.collidesWith(ball)){
                ball.setSpeedX(-ball.getSpeedX());
                ball.setSpeedY(-ball.getSpeedY());
                enemyhitpoint--;
                        if(enemyhitpoint == 0){
                            enemyhitpoint = 2;
                            removeActorFromWorld(actor);
                        }
            }
            else if (actor.getName().equals("Enemy") && actor.collidesWith(wallsTop)){
               
                actor.setSpeedY(-actor.getSpeedY());
               
            }
            else if (actor.getName().equals("Enemy") && actor.collidesWith(wallsBot)){
               
                actor.setSpeedY(-actor.getSpeedY());
               
            }
           
           
           
        }
    }
 
    //All powerups
    public void powerUps() {
        Random rand = new Random();
        Random rand2 = new Random();
        int randomNum = rand.nextInt((100 - 0));
        int wPowerUp = rand2.nextInt((100 - 0));
       
        if (randomNum > 40) {
            System.out.println(wPowerUp + " Print Out");
            //LongBat
            if (wPowerUp <= 17) {
                bat.updateImage(new Image(getClass().getResourceAsStream("/resources/" + "bat_yeah2.png")));
                bat.setHeight(250);
                batLong = true;
           
                batShort = false;
            }
           
            //SmallBat
            else if (wPowerUp <= 34) {
                bat.updateImage(new Image(getClass().getResourceAsStream("/resources/" + "bat_yeah3.png")));
                bat.setHeight(175);
                batShort = true;
           
                batLong = false;
            }
           
            //FireBall
            else if (wPowerUp <= 51) {
                ball.updateImage(new Image(getClass().getResourceAsStream("/resources/" + "fire_ball.png")));
                fireBall = true;
            }
           
           
            //Gravity
            else if (wPowerUp <= 68) {
               gravity = true;
               if (gravity == true) {
                   speedDown = false;
               }
            }
           
            //SpeedDown
            else if (wPowerUp <= 85) {
                speedDown = true;
 
                if (speedDown == true) {
                   gravity = false;
                }
               
            }
           
            //3Split
            else if (wPowerUp <= 100) {
               if (multiBall == true) {
               multiball = new Ball("MultiBall", "multi_ball.png", 30);
               this.multiball.setBallHeight(50);
               this.multiball.setBallWidth(50);
               addToWorld(multiball, 1000, 200, 0, 0, 1);
               multiball.setSpeedX(-20);
               multiball.setSpeedY(-3);
               
               
               multiball2 = new Ball("MultiBall", "multi_ball.png", 30);
               this.multiball2.setBallHeight(50);
               this.multiball2.setBallWidth(50);
               addToWorld(multiball2, 1000, 600, 0, 0, 1);
               multiball2.setSpeedX(-18);
               multiball2.setSpeedY(3);
               }
               
               multiBall = false;
 
            }
           
        }
    }
   
   
    public void keyPressed(KeyCode id) {
 
        System.out.println("You pressed key: " + id.toString());
        if (getGameState() != GameState.Playing) {
            return;
        }
        if (id == KeyCode.UP) {
            bat.setSpeedY(-15);
            if (ballAlive == false) {
                ball.setSpeedY(-30);
 
            }
        } else if (id == KeyCode.DOWN) {
            bat.setSpeedY(15);
            if (ballAlive == false) {
                ball.setSpeedY(30);
 
            }
        }
 
        if (id == KeyCode.SPACE) {
 
            if (ballAlive == false) {
                ballAlive = true;
                ball.setSpeedX(-20);
 
                ball.setSpeedY(-3);
               
                if(gravity == true){
                    gravityOnBat = false;
                   
                }
 
            }
        }
 
        if (id == KeyCode.ESCAPE) {
            setGameState(TitleScreen);
            removeAllActors();
           
 
        }
 
    }
   
    void keyReleased(KeyCode id) {
        System.out.println("You released key: " + id.toString());
 
        if (id == KeyCode.UP) {
            if ((bat.getSpeedY() < 0)) {
 
                bat.setSpeedY(0);
 
            }
            if (ballAlive == false) {
                ball.setSpeedY(0);
            }
 
        } else if (id == KeyCode.DOWN) {
 
            if ((bat.getSpeedY() > 0)) {
 
                bat.setSpeedY(0);
 
            }
 
            if (ballAlive == false) {
                ball.setSpeedY(0);
            }
 
        } else if (id == KeyCode.LEFT) {
            if (bat.getSpeedX() < 0) {
 
                bat.setSpeedX(0);
 
            }
 
        } else if (id == KeyCode.RIGHT) {
            if (bat.getSpeedX() > 0) {
 
                bat.setSpeedX(0);
 
            }
 
        } else if (id == KeyCode.SPACE) {
 
            if (bat.getSpeedY() < 0) {
                ball.setSpeedX(0);
            }
 
        }
    }
 
    public void removeAllActors() {
        for (Actor actor : actors) {
            gui.removeImageView(actor.getImageView());
        }
        actors.clear();
 
    }
 
    public void mousePressed(boolean leftMouse, int x, int y) {
        System.out.printf("Mouse clicked %s, x = %d, y = %d\n", leftMouse ? "LEFT BUTTON" : "OTHER BUTTON", x, y);
    }
 
    public GameState getGameState() {
        return gameState;
    }
 
    /**
     * @param gameState the gameState to set
     */
    public void setGameState(GameState gameState) {
        System.out.printf("Game State changed: %s -> %s\n", this.gameState.toString(), gameState.toString());
        this.gameState = gameState;
 
        gui.updateFromState(gameState);
    }
 
    public void ballPaddle() {
       
       
        if (gravity == false) {
           
            if (ballAlive == false) {
               
                ball.setY(bat.getY() + 90);
               
            }
        }
       
       
    }
   
   
 
}
//end of Game classd of Game class